/*
【例3】实现异质单链表类。

大学人员分为两类，大学人员分为两类，一类是教学人员，一类是非教学人员。
这两类人员的信息管理系统中一部分信息内容不同，另一部分信息内容相同。
设教学人员的信息包括姓名、年龄和专业编号；非教学人员的信息包括姓名、
年龄和业绩评定。现邀请设计一个能同时存储学习教学人员和非教学人员的异质单链表类。
*/
#include <iostream>
#include <string>

using namespace std;

class Person {
	protected:
		string name;
		int age;
	
	public:
		Person * next;
		Person(string name, int age) {
			this->name = name;
			this->age = age;
            next = NULL;
		};
		virtual ~Person() {
			// cout << "Deconstructing Person" << endl;
		}
		virtual void show() {
			cout << "Name : " << name << endl;
			cout << "Age : " << age << endl;
		}
};

class Teacher : public Person {
	private:
		long number;

	public:
		Teacher(string name, int age, long number): Person(name, age), number(number) {}
		~Teacher() {
			// cout << "Deconstructing Teacher" << endl;
		}
		void show() {
			Person::show();
			cout << "Professional Number: " << number << endl;
		}
};

class Noteacher: public Person {
	private:
		int achievement;

	public:
		Noteacher(string name, int age, int achievement): Person(name, age), achievement(achievement) {}
		~Noteacher() {
			// cout << "Deconstructing Noteacher" << endl;
		}
		void show() {
			Person::show();
			cout << "Achievement : " << achievement << endl;
		}
};

// LinkList
class Derived {
	private:
		Person * head;
		int size;
	
	public:
		Derived(): head(NULL), size(0) {}
		~Derived();
		void push_front(Person * p);
		void show();
};

Derived::~Derived() {
	Person * cur = head;
	Person * p;
	while(cur != NULL) {
		p = cur;
		cur = cur->next;
        delete p;
	}
}

void Derived::push_front(Person * p) {
	// Person **cur = &head;
    if(head == NULL) {
        head = p;
		// (*cur)->show();
        return ;
    }

	// cur->show();
    p->next = head->next;
    head->next = p;
    return ;
}

void Derived::show() {
	Person * cur = head;

	while(cur != NULL) {
		cur->show();
        cur = cur->next;
	}
}

int main(int argc, char * argv[]) {
    Derived data;
    Person * p;
    Teacher *t1 = new Teacher("a", 12, 9999887);
    p = t1;
    data.push_front(p);
    // p->show();
    
    Teacher *t2 = new Teacher("b", 13, 912612);
    p = t2;
    data.push_front(p);
    // p->show();

    Noteacher *n1 = new Noteacher("nc", 4, 927);
    p = n1;
    data.push_front(p);
    // p->show();

    Noteacher *n2 = new Noteacher("nd", 123, 342);
    p = n2;
    data.push_front(p);

    data.show();

	
	return 0;
}
